package com.aiden.app.common.http.adapter;

import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import com.aiden.app.common.http.BaseResponse;
import com.aiden.app.common.http.ServerErrorHandling;
import com.aiden.app.common.http.config.HttpGlobalConfig;
import com.aiden.app.common.util.LogUtils;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Callback;
import retrofit2.Response;

import java.lang.reflect.Type;
import java.util.concurrent.atomic.AtomicBoolean;

public class LiveDataCallAdapter<R> implements CallAdapter<R, LiveData<R>> {

    private static final String LOG_TAG = LiveDataCallAdapter.class.getSimpleName();
    private final Type responseType;

    LiveDataCallAdapter(Type responseType) {
        this.responseType = responseType;
    }

    @NonNull
    @Override
    public Type responseType() {
        return responseType;
    }

    @NonNull
    @Override
    public LiveData<R> adapt(@NonNull final Call<R> call) {
        return new MutableLiveData<R>() {
            AtomicBoolean started = new AtomicBoolean(false);

            @Override
            protected void onActive() {
                super.onActive();
                if (started.compareAndSet(false, true)) {
                    call.enqueue(new Callback<R>() {
                        @Override
                        public void onResponse(@NonNull Call<R> call, @NonNull Response<R> response) {
                            BaseResponse responseData = new BaseResponse();
                            if (response.isSuccessful()) {
                                if (response.body() != null) {
                                    BaseResponse temp = (BaseResponse) response.body();
                                    responseData.setData(temp.getData());
                                    responseData.setErrorCode(temp.getErrorCode());
                                    responseData.setErrorMsg(temp.getErrorMsg());
                                    responseData.setSuccessful(responseData.getData() != null);
                                } else {
                                    responseData.setSuccessful(false);
                                    responseData.setErrorCode(String.valueOf(HttpGlobalConfig.SERVICE_EXCEPTION));
                                    responseData.setErrorMsg("网络异常");
                                }
                                LogUtils.INSTANCE.d(LOG_TAG, response.toString());
                            } else {
                                if (response.errorBody() != null) {
                                    LogUtils.INSTANCE.e(LOG_TAG, response.errorBody().toString());
                                }
                                responseData.setErrorMsg("网络异常");
                                responseData.setErrorCode(String.valueOf(response.code()));
                                responseData.setSuccessful(false);
                                responseData.setData(null);

                            }
                            postValue((R) responseData);
                        }

                        @SuppressWarnings("uncheked")
                        @Override
                        public void onFailure(@NonNull Call<R> call, @NonNull Throwable t) {
                            // 轮询修改baseUrl
                            BaseResponse<R> baseResponse = new BaseResponse<>();
                            baseResponse.setData(null);
                            baseResponse.setErrorCode(String.valueOf(HttpGlobalConfig.FAILURE_CODE));

                            // 处理网络异常提示
                            ServerErrorHandling.INSTANCE.handling(t, exception -> {
                                switch (exception) {
                                    case BAD_NETWORK:
                                    case PARSE_ERROR:
                                    case CONNECT_ERROR:
                                    case UNKNOWN_ERROR:
                                        baseResponse.setErrorMsg("网络异常");
                                        break;
                                    case CONNECT_TIMEOUT:
                                        baseResponse.setErrorMsg("连接超时");
                                        break;
                                }
                            });

                            baseResponse.setSuccessful(false);
                            postValue((R) baseResponse);
                        }
                    });
                }
            }
        };
    }
}
